import axios from 'axios'
// import router from '../router/index'
// import store from '../store/index'
import {
    ElMessage,
    ElMessageBox,
    ElLoading
} from 'element-plus';

//提示函数
const tip = msg => {
    ElMessage.warning({
        message: msg,
        type: 'warning'
    });
}
//跳转登录页，携带当前页面路由，登录后返回当前页面
const toLogin = () => {
    // router.replace({
    //     path: '/login',
    //     query: {
    //         redirect: router.currentRoute.fullPath
    //     }
    // })
}
//错误处理
const errorHandle = (status, other) => {
    switch (status) {
        //未登录
        case 401:
            toLogin();
            break;
            //403 token过期，清除token并跳转登录页
        case 403:
            tip('登录过期，请重新登录');
            localStorage.removeItem('token');
            // store.commit(loginSuccess, null);
            setTimeout(() => {
                toLogin();
            }, 1000);
            break;
            //请求不存在
        case 404:
            tip('请求资源不存在');
            break;
        default:
            console.log(other)
    }
}

// 用于存储目前状态为pending的请求标识信息
let pendingRequest = [];

//取消请求-请求拦截中的处理
const CancelToken = config => {
    // 区别请求的唯一标识，这里用方法名+请求路径
    const requestMark = `${config.method} ${config.url}`;
    // 找当前请求的标识是否存在pendingRequest中，即是否重复请求了
    const markIndex = pendingRequest.findIndex(item => {
        return item.name === requestMark;
    });
    // 存在，即重复了
    if (markIndex > -1) {
        // 取消上个重复的请求
        pendingRequest[markIndex].cancel();
        // 删掉在pendingRequest中的请求标识
        pendingRequest.splice(markIndex, 1);
    }
    // （重新）新建针对这次请求的axios的cancelToken标识
    const CancelToken = axios.CancelToken;
    const source = CancelToken.source();
    config.cancelToken = source.token;
    // 设置自定义配置requestMark项，主要用于响应拦截中
    config.requestMark = requestMark;
    // 记录本次请求的标识
    pendingRequest.push({
        name: requestMark,
        cancel: source.cancel,
    });
    return config;
};

//取消请求-响应拦截中的处理
const CancelTokenResponse = config => {
    // 根据请求拦截里设置的requestMark配置来寻找对应pendingRequest里对应的请求标识
    const markIndex = pendingRequest.findIndex(item => {
        return item.name === config.requestMark;
    });
    // 找到了就删除该标识
    markIndex > -1 && pendingRequest.splice(markIndex, 1);
}

//创建axios实例
var instance = axios.create({
    transformRequest: [data => { // 请求数据处理（防止后端接收不到参数）
        if (Object.prototype.toString.call(data) === '[object FormData]') {
            return data;
        }
        return JSON.stringify(data);
        // return Qs.stringify(data);
    }],
    transformResponse: [data => { // ie兼容性（解决无返回数据问题）
        if (Boolean(window.ActiveXObject) || 'ActiveXObject' in window || navigator.userAgent.indexOf('MSIE') >= 0) {
            return JSON.parse(data);
        }
        return data;
    }],
    baseURL: import.meta.env.VITE_APP_API,
    timeout: 1000 * 12
})

//设置post请求头
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

//请求拦截器
instance.interceptors.request.use(
    config => {
        config = CancelToken(config);
        // const token = store.state.token;
        // token && (config.headers.Authorization = token);
        return config;
    },
    error => Promise.reject(error)
)
//响应拦截器
instance.interceptors.response.use(
    res => {
        //请求结束就从pendingRequest删除请求标志
        CancelTokenResponse(res.config);
        return res.status === 200 ? Promise.resolve(res) : Promise.reject(res);
    },
    error => {
        const {
            response
        } = error;
        //请求已经发出，返回结果不在2xx的范围
        if (response.data) {
            // console.log(response);
            CancelTokenResponse(response.config);
            errorHandle(response.status, response.data.message);
            return Promise.reject(response);
        } else {
            //断网情况,刷新重新获取数据
            if (!window.navigator.onLine) {
                store.commit('changeNetwork', false);
            } else {
                return Promise.reject(error);
            }
        }
    }
)

// export default instance;
export default {
    getData({
        url,
        method,
        params,
        baseURL,
        responseType,
        headers
    }) {
        let loading = ElLoading.service({
            customClass: 'pageLoading',
            background: 'transparent'
        });

        return new Promise((resolve, reject) => {
            if (params && params.isMock) {
                let res = {
                    data: $server(url)
                };

                resolve(res);
                loading.close();
                return;
            }
            let methods = method || 'post',
                obj = methods !== 'get' ? {
                    data: params
                } : {
                    params: params
                };

            obj = headers ? {
                ...obj,
                headers: headers
            } : obj;
            instance({
                ...obj,
                baseURL: baseURL || import.meta.env.VITE_APP_API,
                responseType: responseType || 'json',
                method: methods,
                url: url
            }).then(res => {
                loading.close();
                // console.log(res);
                if (res.data && (res.data.load > 0 || res.status === 200 || res.status === 201)) {
                    resolve(res);
                } else {
                    ElMessageBox({
                        title: '提示',
                        message: res.data.message || '请求响应失败，请重试！',
                        showCancelButton: true,
                        showConfirmButton: true,
                        type: 'warning'
                    }).then(action => {
                        if (action === 'confirm') {
                            this.getData({
                                url,
                                method,
                                params,
                                baseURL,
                                responseType,
                                headers
                            });
                        }
                    }).catch(() => {
                        Message.closeAll();
                        Message({
                            type: 'info',
                            showClose: true,
                            message: '已取消！'
                        });
                    });
                }
            }).catch(err => {
                loading.close();
                // console.log(res);
                ElMessageBox({
                    title: '提示',
                    message: err.message || '请求响应失败，请重试！',
                    showCancelButton: true,
                    showConfirmButton: true,
                    type: 'warning'
                }).then(action => {
                    if (action === 'confirm') {
                        this.getData({
                            url,
                            method,
                            params,
                            baseURL,
                            responseType,
                            headers
                        });
                    }
                }).catch(() => {
                    Message.closeAll();
                    Message({
                        type: 'info',
                        showClose: true,
                        message: '已取消！'
                    });
                });
                reject(err);
            });
        });
    },
    // 上传文件
    uploadFile({
        url,
        method,
        params,
        baseURL
    }) {
        let loading = ElLoading.service({
            customClass: 'pageLoading',
            background: 'transparent'
        });

        return new Promise((resolve, reject) => {
            let methods = method || 'post',
                formData = new FormData(),
                paramsObj = Object.assign({}, params),
                obj = {};

            for (let i in paramsObj) {
                if (paramsObj[i] in paramsObj) {
                    delete paramsObj[i];
                    break;
                }
            }
            for (let i in paramsObj) {
                if (Array.isArray(paramsObj[i]) && paramsObj[i][0] instanceof File) {
                    for (let j in paramsObj[i]) {
                        formData.append(i, paramsObj[i][j], new Date().getTime());
                    }
                } else {
                    formData.append(i, paramsObj[i]);
                }
            }
            obj = methods !== 'get' ? {
                data: formData
            } : {
                params: formData
            };
            instance({
                ...obj,
                url: url,
                baseURL: baseURL || import.meta.env.VITE_APP_API,
                method: methods,
                headers: {
                    'Content-Type': 'multipart/form-data'
                }
            }).then(res => {
                loading.close();
                if (res.data && (res.data.load > 0 || res.status === 200 || res.status === 201)) {
                    resolve(res);
                } else {
                    ElMessageBox({
                        title: '提示',
                        message: res.data.message || '请求响应失败，请重试！',
                        showCancelButton: true,
                        showConfirmButton: true,
                        type: 'warning'
                    }).then(action => {
                        if (action === 'confirm') {
                            this.uploadFile({
                                url,
                                method,
                                params,
                                baseURL
                            });
                        }
                    }).catch(() => {
                        Message.closeAll();
                        Message({
                            type: 'info',
                            showClose: true,
                            message: '已取消！'
                        });
                    });
                }
            }).catch(err => {
                loading.close();
                ElMessageBox({
                    title: '提示',
                    message: err.message || '请求响应失败，请重试！',
                    showCancelButton: true,
                    showConfirmButton: true,
                    type: 'warning'
                }).then(action => {
                    if (action === 'confirm') {
                        this.uploadFile({
                            url,
                            method,
                            params,
                            baseURL
                        });
                    }
                }).catch(() => {
                    Message.closeAll();
                    Message({
                        type: 'info',
                        showClose: true,
                        message: '已取消！'
                    });
                });
                reject(err);
            });
        });
    }
};